/********************************************************************************************************
 * @file	iso_stack.h
 *
 * @brief	This is the header file for BLE SDK
 *
 * @author	BLE GROUP
 * @date	2020.06
 *
 * @par     Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
 *          All rights reserved.
 *
 *          Redistribution and use in source and binary forms, with or without
 *          modification, are permitted provided that the following conditions are met:
 *
 *              1. Redistributions of source code must retain the above copyright
 *              notice, this list of conditions and the following disclaimer.
 *
 *              2. Unless for usage inside a TELINK integrated circuit, redistributions
 *              in binary form must reproduce the above copyright notice, this list of
 *              conditions and the following disclaimer in the documentation and/or other
 *              materials provided with the distribution.
 *
 *              3. Neither the name of TELINK, nor the names of its contributors may be
 *              used to endorse or promote products derived from this software without
 *              specific prior written permission.
 *
 *              4. This software, with or without modification, must only be used with a
 *              TELINK integrated circuit. All other usages are subject to written permission
 *              from TELINK and different commercial license may apply.
 *
 *              5. Licensee shall be solely responsible for any claim to the extent arising out of or
 *              relating to such deletion(s), modification(s) or alteration(s).
 *
 *          THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 *          ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *          WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *          DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
 *          DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *          (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *          LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *          ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *          (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *          SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *******************************************************************************************************/
#ifndef ISO_STACK_H_
#define ISO_STACK_H_


#include "stack/ble/ble_common.h"
#include "stack/ble/ble_stack.h"
#include "stack/ble/ble_format.h"
#include "stack/ble/controller/ll/acl_conn/acl_stack.h"
#include "stack/ble/controller/csa/csa_stack.h"
#include "stack/ble/controller/ll/iso/iso_test.h"


/******************************* iso_config start ******************************************************************/

/////////////////////// FOR CIG //////////////////////
#ifndef			LL_CIG_MST_NUM_MAX
#define 		LL_CIG_MST_NUM_MAX              			(TSKNUM_CIG_MST) //Number of CIG MST tasks supported
#endif

#ifndef			LL_CIG_SLV_NUM_MAX
#define 		LL_CIG_SLV_NUM_MAX              			(TSKNUM_CIG_SLV) //Number of CIG SLV tasks supported
#endif

#ifndef			LL_CIS_IN_PER_CIG_MST_NUM_MAX
#define 		LL_CIS_IN_PER_CIG_MST_NUM_MAX				4 //The number of CIS supported by each CIG Mst
#endif

#ifndef			LL_CIS_IN_PER_CIG_SLV_NUM_MAX
#define 		LL_CIS_IN_PER_CIG_SLV_NUM_MAX				4 //The number of CIS supported by each CIG Slv
#endif

#ifndef			LL_SE_IN_PER_CIS_NUM_MAX
#define 		LL_SE_IN_PER_CIS_NUM_MAX              		8 //The number of SEs supported by each CIS
#endif

#ifndef			LL_SE_IN_PER_CIG_MST_NUM_MAX
#define 		LL_SE_IN_PER_CIG_MST_NUM_MAX              	(LL_CIS_IN_PER_CIG_MST_NUM_MAX * LL_SE_IN_PER_CIS_NUM_MAX)
#endif

//Not used now [cig_slv]
#ifndef			LL_SE_IN_PER_CIG_SLV_NUM_MAX
#define 		LL_SE_IN_PER_CIG_SLV_NUM_MAX              	(LL_CIS_IN_PER_CIG_SLV_NUM_MAX * LL_SE_IN_PER_CIS_NUM_MAX)
#endif

#ifndef			LL_CIS_CONN_NUM_MAX							//Maximum number of supported CIS (including CIG MST and SLV)
#define 		LL_CIS_CONN_NUM_MAX              			(LL_CIS_IN_PER_CIG_SLV_NUM_MAX * LL_CIG_SLV_NUM_MAX + \
															 LL_CIS_IN_PER_CIG_MST_NUM_MAX * LL_CIG_MST_NUM_MAX)
#endif


/////////////////////// FOR BIG //////////////////////
#ifndef			LL_BIG_BCST_NUM_MAX
#define			LL_BIG_BCST_NUM_MAX							(TSKNUM_BIG_BCST) //Number of BIG BCST tasks supported
#endif

#ifndef			LL_BIG_SYNC_NUM_MAX
#define			LL_BIG_SYNC_NUM_MAX							(TSKNUM_BIG_SYNC) //Number of BIG SYNC tasks supported
#endif

#ifndef			LL_BIS_IN_PER_BIG_BCST_NUM_MAX
#define			LL_BIS_IN_PER_BIG_BCST_NUM_MAX				4 //The number of BIS supported by each BIG BCST
#endif

#ifndef			LL_BIS_IN_PER_BIG_SYNC_NUM_MAX
#define			LL_BIS_IN_PER_BIG_SYNC_NUM_MAX				4 //The number of BIS supported by each BIG SYNC
#endif

#ifndef			LL_SE_IN_PER_BIS_NUM_MAX
#define 		LL_SE_IN_PER_BIS_NUM_MAX              		4 //The number of SEs supported by each BIS
#endif

#ifndef			LL_SE_IN_PER_BIG_BCST_NUM_MAX
#define 		LL_SE_IN_PER_BIG_BCST_NUM_MAX              	(LL_BIS_IN_PER_BIG_BCST_NUM_MAX * LL_SE_IN_PER_BIS_NUM_MAX)
#endif

#ifndef			LL_SE_IN_PER_BIG_SYNC_NUM_MAX
#define 		LL_SE_IN_PER_BIG_SYNC_NUM_MAX              	(LL_BIS_IN_PER_BIG_SYNC_NUM_MAX * LL_SE_IN_PER_BIS_NUM_MAX)
#endif

#ifndef			LL_BIS_TOTAL_NUM_MAX						//Maximum number of supported BIS (including BIG BCST and SYNC)
#define 		LL_BIS_TOTAL_NUM_MAX              			(LL_BIS_IN_PER_BIG_BCST_NUM_MAX * LL_BIG_BCST_NUM_MAX + \
															 LL_BIS_IN_PER_BIG_SYNC_NUM_MAX * LL_BIG_SYNC_NUM_MAX)
#endif


#define			TLK_T_MSS										(350)//350

#define			TLK_TX_TRIG_OFFSET								(70)
#define			TLK_TX_STL_OFFSET								(150)
#define			TLK_TX_SEND_OFFSET								(TLK_TX_TRIG_OFFSET + TLK_TX_STL_OFFSET)
#define			TLK_TM_DELAY									(20)




#define  ISO_TESt_SUPPORT_MAX_NUM		(2)


typedef enum{

	ISO_TEST_DISABLE,
	ISO_TEST_TRANSMIT_MODE,
	ISO_RECEIVE_MODE,

}iso_test_mode_t;

typedef struct{
  	u32	successCnt;
  	u32 missedCnt;
  	u32	failedCnt;
  	u32 expectCnt;
}iso_test_receive_infor_t;

typedef struct{
  	u32	send_pkt_cnt;
  	u32 isoTestSendTick;
}iso_test_trasmit_infor_t;

typedef struct{

	u8  occupy;
  	u8 	isoTestMode;  // 0: test mode disable, 1: transmit  2: receive
  	u8  isoTest_payload_type;
  	u8  rsvd1;

	union{
			iso_test_receive_infor_t recMode;
			iso_test_trasmit_infor_t tranMode;
	};

}iso_test_param_t;

typedef enum{
	ISO_TEST_ZERO,
	ISO_TEST_VARIABLE,
	ISO_TEST_MAXIMUM,
}iso_test_payload_type_t;

/******************************* iso_config end ******************************************************************/




/******************************* iso start ******************************************************************/
ble_sts_t 	blc_hci_le_readBufferSize_v2_cmd(u8 *pData);
ble_sts_t	blc_hci_le_read_iso_tx_sync_cmd(u16 iso_connHandle, u8 *pData);
u8			blt_ll_selectNxtSubEvtChn(ll_mgrChnParam_t *pChnParam, u16 chnIdentifier, u8 SubEventNum, u64 eventCnt, u8 skip);
/******************************* iso end ********************************************************************/










/******************************* cis start ******************************************************************/

#define		CIG_SLOT_BUILD_MSK				BIT(7)
#define		CIS_SLOT_BUILD_MSK				BIT(6)

#define		CIS_FLOW_IDLE					0
#define		CIS_FLOW_SLAVE_REQ_HOST			BIT(0)
#define		CIS_FLOW_SLAVE_SEND_CIS_RSP		BIT(1)
#define		CIS_FLOW_SLAVE_REJECT_CIS_REQ	BIT(2)
#define		CIS_FLOW_SLAVE_WAIT_CIS_IND		BIT(3)
#define		CIS_FLOW_MASTER_START_NEW_CIS	BIT(0)
#define		CIS_FLOW_MASTER_SEND_CIS_REQ	BIT(1)
#define		CIS_FLOW_MASTER_SEND_CIS_IND	BIT(2)
#define		CIS_FLOW_MASTER_REJECT_CIS_RSP	BIT(3)
#define		CIS_FLOW_CIS_SYNC				BIT(5)
#define		CIS_FLOW_CIS_SYNC_SUCCESS		BIT(6)
#define		CIS_FLOW_CIS_SYNC_FAIL			BIT(7)

#define 	CIS_ROLE_MASTER           		1
#define 	CIS_ROLE_SLAVE             		0
#define		CIS_ID_INVALID		            0xFF

#define		BLT_CIS_HANDLE					BIT(5)  //CIS connection handle, BIT(5), 0x0020
#define		BLT_CIS_CONN_HANDLE				BLT_CIS_HANDLE
#define		BLT_CIS_IDX_MSK					0x0F  //15 most, though standard 31 max, 15 is enough in our SDK
#define		SLOT_BUILD_IDX_MSK				0x0F



//ISO CIS TX Data Buffer struct begin
typedef	struct {
//	u64		ft_cisEventCnt;		/* 39-bit cisEventCounter: FT_E = E + FT -1, cisPayloadNumber  [E*BN, (E+1)*BN-1] */
	u64 	payloadNumber;
	u64		eventCnt;

//	u32		ft_cisSubEvtNum;	/* FT_U = NSE C floor (NSE  BN)  (BN C 1 C cisPayloadNumber mod BN) */

	u16		offset;
	u8 		RFU[3]; //4B align
	rf_packet_ll_data_t isoTxPdu;
}cis_tx_pdu_t;

typedef	struct {
	u32		fifo_size;

	u16     full_size; //fifo_size plus additional header
	u8		fifo_num;
	u8		rsvd;

	cis_tx_pdu_t* cis_tx_pdu;
}cis_tx_pdu_fifo_t;




//ISO CIS RX Data Buffer struct begin
typedef	struct {
	u64 	curRcvdPldNum;	       //The cisPayloadNum corresponding to the received CIS Data PDU.
	u64		rcvdPldCisEventCnt;
	u32		rcvdPldCisAnchorTick;  //Calculate the corresponding CIS reference anchor value according to the received peer CisPayloadNum.
	u32     rxFlushedFlg;	       //Passed it's Flush Point

	rf_packet_ll_data_t isoRxPdu;
}cis_rx_pdu_t;

typedef	struct {
	u16		fifo_size;
	u16     full_size; //fifo_size plus additional header

	u16		fifo_num;
	u8		wptr;
	u8		rptr;

//	iso_rx_pdu_fifo_t_t* iso_rx_pdu_fifo_t;  //todo can use rf_packet_ll_data_t isoRxPdu;
	rf_packet_ll_data_t *isoRxPdu;  //todo
}iso_rx_pdu_fifo_t;




//ISO CIS/bis RX Event Buffer strcut begin
typedef	struct iso_rx_evt_tag{
	struct iso_rx_evt_tag	*next;
//	u64						curRcvdEventCnt;		//the current eventcnt that receiving the payloadNum
	u64					 	curRcvdPldNum;      //The cisPayloadNum corresponding to the received CIS Data PDU.
	rf_packet_ll_data_t* 	pCurrIsoRxPdu;      //ISO RX PDU buffer address
	u32	    				idealPldAnchorTick; //Calculate the corresponding CIS reference anchor value according to the received peer CisPayloadNum.
	u16	    				handle;             //Current CIS connection/BIS handle
	u8						payloadLen;		    //The length indicates the size of the CIS Payload and MIC, if included.
	u8						rsvd1;               //align
	u32						rsvd2;
}iso_rx_evt_t;


my_fifo_t 				bltCisRxEvt;



//CIS parameters
_attribute_aligned_(4)
typedef struct
{

// 0x00	 //
  	u8  	cis_connHandle;		/* Used to identify a CIS */
  	u8     	cigId;				//cigId is allocated by Host
  	u8		cisId;				//cisId is allocated by Host, 0x00 ~ 0xEF
  	u8		cis_occupied;		//indicate whether this CIS is used now, should clear when: 1.CIG remove; 2. ACL_conn terminate; 3.

  	u8		established;		//CIS is occupied and established, should allocate slot
  	u8		cis_tim_en;			// CIS slave timing enable, should allocate slot
  	u8		nse;
  	u8		link_acl_handle;	//link ACL_conn_hancle, associated ACL connection handle, for CIS master: 0x80/0x81...; for CIS slave 0x40,0x41....
  								//u8 is enough, due to our special design
  								//reason for not use link_acl_conn_idx: 0 has confusing meanings, one for master 0x80, one for data clear
  								//TODO, when CIS destroy, clear it. so acl_handle is used to judge whether a ACL connection is  associated
  	u8		cur_se_index;	//TODO: no need, use cisSubEventCnt
 	u8      cis_framed;		/* Framed indicates whether the CIS carries framed or unframed data */
 	u8		cis_receive_packet;
 	u8		cis_receive_new_packet;

 	u8		conn_successive_miss;
	u8 		conn_peer_terminate;
	u8 		conn_local_terminate;
	u8		cis_terminate_reason;


// 0x10	 //
	u8		conn_chn_hop;
	u8      ll_enc_busy;
	u8		connState;			 // 0/Conn_Complete/Conn_Establish
	u8		disconn_evt;

	u8		cisSubEventCnt;		//Internal sub-event accumulation, the first subeventcnt is 1, subevent <=nse.Need to be cleared before each CIG event is triggered
	u8      cisCurrPduAcked;    //CIS Data was ACKed in current subEvent
	u8      cis_cie;            //Close Isoc Event
	u8		cisConnChn;

	//CIS TX && RX buffer ctrl
	u8		isoPduTxFifoWptr;
	u8		isoPduTxFifoRptr;
	u8      cisPduNewData;
	u8      closeIsoEvent; 		/* 1 means close current CIS event */
						/// current RX pdu pointer ///
	void* 	pISOrxPdu;	//Rx irq handler will init it's value


// 0x20	 //
	volatile u64 curSendPldNum;  //When CIS is first established, it is initialized to 0, and it is used locally to record the currently sent CisPayloadNum. Every time a CIS Data PDU is sent or FT is incremented
	volatile u64 curRcvdPldNum;	 //When CIS is established, it is initialized to 0. It is used locally to record the currently received CisPayloadNum. Every time a CIS Data PDU is received or the FT is incremented
	                         /// L && F is used to determine the peer_CisPayloadNum corresponding to the received peer CIS data PDU ///

// 0x30	 //
	u64     lastAckedPldNum; //L be the last PDU that you have acknowledged
	u64		lastPassFtPldNum;//F be the last PDU that has passed its flush point


// 0x40	 //
	//for CIS flowctrl
	u8		local_sn;
	u8		local_nesn;
	u8      peer_lastSN;
	u8      cisPduCrcErr;

	u8		cis_rx_num;
	u8		markLastPduType; //In the TX interrupt, mark whether the sent CIS data is a NULL packet
	u8	rdyToSentNullPkt;//Whether the data currently selected to be sent is a NULL packet: 1 NULL PDU, 0 Data PDU
	u8		cisRole; 		 //1:master CIS role; 0:Slave CIS role

 	u8  	phy_m2s;		/* The transmitter PHY of packets from the master */
  	u8		phy_s2m;		/* The transmitter PHY of packets from the slave */
  	u8		bn_m2s;
  	u8		bn_s2m;

  	u8		rtn_m2s; 		/* only for CIS master: Maximum number of times every CIS Data PDU should be retransmitted from the master to slave */
  	u8  	rtn_s2m; 		/* only for CIS master: Maximum number of times every CIS Data PDU should be retransmitted from the slave to master */
    u8		ft_m2s; 			/* The flush timeout in multiples of ISO_Interval for each payload sent from the master to slave */
	u8		ft_s2m; 			/* The flush timeout in multiples of ISO_Interval for each payload sent from the slave to master */


// 0x50	 //
	u8		curCisPhy;
	u8		cig_idx;			  //cigIdx is used to find CIG
	u16		cisBeginConnEventCnt; //similar to instant

  	u16		max_sdu_m2s;	/* Maximum size, in octets, of the payload from the master  Host */
	u16		max_sdu_s2m;	/* Maximum size, in octets, of the payload from the slave  Host */

	u16		max_pdu_m2s;
	u16		max_pdu_s2m;

	u32 	MPTM_T_IFS_MPTS;	//unit: uS


// 0x60	 //
	u32     se_length_us;		/* SE_Length is the maximum length of a subevent, SE_Length = MPTM + T_IFS + MPTS + T_MSS */
//	u32		MPTm_tick;			/* MPTM and MPTS shall equal the time taken by the master and slave respectively to transmit a packet containing a CIS PDU with a payload of Max_PDU octets */
//	u32		MPTs_tick;      	/* MPTM and MPTS shall equal the time taken by the master and slave respectively to transmit a packet containing a CIS PDU with a payload of Max_PDU octets */

	u32     cis_arrgmt_en;      /* cis has reached the ACL instant anchor point specified by LL_CIS_IND, and can let cig schedule scheduling */

	u32 	sub_intvl_us;		/* Sub_Interval is the time between start of two consecutive subevents of a CIS*/
	u32 	sub_intvl_tick;
	u32     se_length_tick;

	u32     iso_intvl_tick;		/* Time between consecutive CIS anchor points */;


  	u32		sdu_int_m2s_tick;	/* The interval, in microseconds, of periodic SDUs */
  	u32		sdu_int_s2m_tick;	/* The interval, in microseconds, of periodic SDUs */
	u32		own_cisOffsetMin_us;
	u32		own_cisOffsetMax_us;
	u32		peer_cisOffsetMin_us;
	u32		peer_cisOffsetMax_us;
	u32		effectCisOffset_us; /* final used cis offset */

//	u32		cisOffsetMin_tick;	/* CIS_Offset_Min shall be set to the proposed minimum time, in microseconds, between the ACL anchor point of
//	                               the connection event with the connection event counter equal to connEventCount and the first CIS anchor point */
//	u32		cisOffsetMax_tick;

	u32		cig_sync_delay;
	u32		cis_sync_delay;
	u32		transLaty_m2s;		/* unit: 1us */
	u32		transLaty_s2m;		/* unit: 1us */
//  u32		cigSyncDly_tick;	/* Timing parameters (CIS_Sync_Delay and CIG_Sync_Delay)  from Master LL for sync ISO data at the application layer */
// 	u32		cisSyncDly_tick;	/* Timing parameters (CIS_Sync_Delay and CIG_Sync_Delay)  from Master LL for sync ISO data at the application layer */
	u32		cis_tick;
	u32		cis_timeout;
	u32		cis_expect_time;	/* TODO */
	u32		cis_anchor_point;	/* TODO */
	s32		cis1stSchedAPsSlot;	/* The first anchor point of CIS scheduling */
	u32		cisSchedFlg;		/* CIS has begun to participate in the scheduling */
	u32		getRxTimestamp;		/* align, u8 enough,TODO */

	u8  	rxSduFifoWptr;
	u8  	rxSduFifoRptr;
	u8 		rxSduStatus;
	u8 		lossFlag;

	u16 	rx_lastPktSeqNum;   //HCI packet sequence number
	u16 	tx_lastPktSeqNum;   	//HCI packet sequence number

	u32 	rx_lastSduTimestamp;//HCI timestamp, SDU synchronization reference
	u32 	tx_lastSduTimestamp;	//HCI timestamp, SDU synchronization reference

	u64 	rx_lastRcvdPldEventCnt; //

	u8 		rx_numSdu2Pdu;  //at receiver1SDU PDU
	u8 		txSduFifoWptr; 	   //tx sdu fifo
	u8 		txSduFifoRptr;
	u8 		tx_first_flag;

	u8 		tx_sdu_sn; 	// the number of PDU sent by current sdu
	u8 		tx_pdu_sn;
	u8 		tx_numSdu2Pdu;
	u8 		tx_numSduEachCisEvent;


	u64 	tx_lastEventCnt;
	u64		tx_lastpldNum;




	u64		cisEventCnt;		/* TODO: u64? Both the master and slave shall have a 39-bit counter cisEventCounter */
	u64		cisPayloadNum;  	/* TODO: u64? Each CIS shall have a 39-bit cisPayloadNumber associated with it */

	// ISO link quality record (Ref Core5.2 | Vol 4,Part E, Page2741)
	u32		tx_unAckedPktsCntr;
	u32		tx_flushedPktsCntr;
	u32		tx_lastSubEvtPktsCntr;
	u32		retransmittedPktsCntr;
	u32		crcErrPktsCntr;
	u32		rxUnrcvedPktsCntr;
	u32		duplicatePktsCntr;

	//Channel parameters
//	ll_mgrChnParam_t chnParam;					//reuse ACL's channel table information, only Channel Identifier different
  	u32		cisAccessAddr;		//AA shall be set to the Access Address of the CIS
  	u32		cisCrcInit;			//Same as the ACL's CRC_Init value
//  u8		nxtRempChmTbl[40];					//reuse ACL's channel table information, only Channel Identifier different
//  u8		nxtNumUsedChn;						//reuse ACL's channel table information, only Channel Identifier different
//  u8		nxtChmTbl[5];						//reuse ACL's channel table information, only Channel Identifier different
  	u16		chnIdentifier;		//BISes use the same channel map as BIG, only ChnId different. Put outside
  							    //the structure 'll_mgrChnParam_t' to reuse channel table information and save RAM


	// encryption concerned

	ble_crypt_para_t crypt;//48 bytes
	u16 rsvd1;


#if (LL_FEATURE_ENABLE_CONNECTIONLESS_ISO)
  	iso_test_param_t	*pIsoTestParam;
#endif

} ll_cis_conn_t;

_attribute_aligned_(4)
typedef struct
{
    u8		maxNum_cig_mst;
    u8		curNum_cig_mst;
    u8		maxNum_cig_slv;
    u8		curNum_cig_slv;

    u8 		maxNum_cisConn;
    u8		latest_cigId;
    u16		u16_rsvd;

    u8 		maxNum_cisMaster;
    u8		curNum_cisMaster;
    u8 		maxNum_cisSlave;
    u8		curNum_cisSlave;

  	u8		cis_pending_cnt;
  	u8		cis_pending_msk;		   // mark which CIS is request by Host, pending now, CIS establish event is not generated
  	u8		ciss_1st_se;		//first sub_event for cis_salve
  	u8		cis_conn_sync; //not use


  	u32		cis_1st_anchor_evtCnt;

}ll_cis_mng_t;

extern ll_cis_conn_t		*global_pCisConn;
extern ll_cis_conn_t		*blt_pCisConn;
extern ll_cis_mng_t			bltCisMng;

extern int					blt_cis_sel;

extern rf_packet_ll_data_t  gCisNullPdu;
extern rf_packet_ll_data_t* pCurrCisPdu;

extern cis_tx_pdu_fifo_t		bltCisPduTxfifo;
extern iso_rx_pdu_fifo_t		bltCisPduRxfifo;




int 		irq_cis_rx(void);
int 	 	blt_cis_connect_common(ll_cis_conn_t *pCisConn);
int 	 	blt_ll_cis_start_common_1(ll_cis_conn_t *pCisConn);
int 	 	blt_ll_cis_start_common_2(ll_cis_conn_t *pCisConn);
int 		blt_ms_iso_procCisConnectionEvent(u16 cisHandle, ll_cis_conn_t *pCisConn);

u8* 		blt_ll_cis_prepare_data_common(ll_cis_conn_t *pCisConn);
void 		blt_ll_cis_flush_timeout_jump(ll_cis_conn_t *pCisConn, u16 jumpCisEvtNum);
void 		blt_ll_cis_flush_timeout_common(ll_cis_conn_t *pCisConn);
void 	    blt_cis_pushRxEvtInfoToFifo(ll_cis_conn_t *pCisConn, rf_packet_ll_data_t* pIsoRxRawPkt);

ble_sts_t 	blt_cisgrp_post_common(void);
ble_sts_t	blt_ll_cis_post_common(ll_cis_conn_t *pCisConn);
ble_sts_t		blc_ll_cis_disconnect(u16 connHandle, u8 reason);
//bool 		blt_ll_cis_pushTxfifo(u16 cis_connHandle, rf_cis_data_hdr_t cisPduHdr, u8* pIsoDataLoad, iso_cis_tx_pdu_para_t cisSeqNoInfo);
//bool 		blt_ll_cis_encryptPdu(u16 cis_connHandle, cis_tx_pdu_t *pdu);

/******************************* cis end ********************************************************************/






















/******************************* cis_master start ******************************************************************/
//ISO interval shall be a multiple of 1.25mS in the range of 5ms to 4S

#define				CIG_MST_FIFONUM				16  //16*5 = 80mS

//	CIG parameters
_attribute_aligned_(4)
typedef struct
{
// 0x00	 //
	u8		cig_index;
  	u8  	cigId;					/* Used to identify the CIG */
  	u8		cig_test_cmd;           // 1 for "LE Set CIG Parameters Test command", FT/Iso_interval/NSE[i]/Max_PDU[i]/BN[i] set by Host
  									// 0 for "LE Set CIG Parameters command", FT/Iso_interval/NSE[i]/Max_PDU[i]/BN[i] set by Controller
  	u8		cig_valid;				// mark if used now, should set and clear in CIG set and remove


  	u8		cis_alloc_count;		// CIS allocate count
  	u8		cis_estab_cnt;			// CIS establish count
  	u8		cis_alloc_msk;			// mark which CIS allocate for current CIG, support 8 CIS max with "u8"
  	u8		cis_estab_msk;			// mark which CIS established			  , support 8 CIS max with "u8"

  	u8		first_cis_flag;   // 0: first CIS
	u8		sca;		/* Slaves_Clock_Accuracy */   //type same as u8
	u8		cis_packing;			// 'cis' but not 'cig'
	u8	    cig_framed;

	u8      cis_total_se_num;   //The cumulative number of cis arrangement mapping tables from the beginning of the idx0 to the last valid se (se may belong to different cis)
	u8      cis_se_en_num;
	u8      cis_arrgmt_next_idx;//Starting idx of cis arrangement mappings
	u8      cis_se_skip;		//If the part of the mapping table that is initially checked is invalid, it will skip to find the next valid CIS.




// 0x10	 //
	u8		ft_m2s; 					/* The flush timeout in multiples of ISO_Interval for each payload sent from the master to slave */
	u8		ft_s2m; 					/* The flush timeout in multiples of ISO_Interval for each payload sent from the slave to master */
	u8		u8_rsvd1;
	u8		u8_rsvd2;

	u16		iso_interval;			/* N * 1.25ms */
  	u16 	max_trans_lat_m2s;		/* Maximum time, in milliseconds, for an SDU to be transported from the master Controller to slave Controller */
  	u16 	max_trans_lat_s2m;		/* Maximum time, in milliseconds, for an SDU to be transported from the slave Controller to master Controller */

  	u16		bSlot_duration_cig;		// u8 is enough
  	u16		sSlot_duration_cig;		// u8 is enough
  	u16		bSlot_interval_cig;      // u16 can handle max 4S




// 0x20	 //
	u32     cis_arrgmt_map_msk; //Which idx are valid in the cis arrangement mapping table
  	u32		cig_sync_delay;	  // unit: uS ? //TODO
	u32		sdu_int_m2s;			/* The interval, in microseconds, of periodic SDUs */
	u32		sdu_int_s2m;			/* The interval, in microseconds, of periodic SDUs */


// 0x30	 //
  	u32		bSlot_first_anchor;		// u8 is enough
	u32 	bSlot_mark_cig;
	u32 	slot_tick_cig;


	u8		u8_rsvd22;
	u8		u8_rsvd33;
	u8		cigTsk_wptr;
	u8		cigTsk_rptr;

	//Attention: if not 4B aligned, task scheduler will collapse. SO variable must 4B aligned above !!!
	sch_task_t	cigTsk_fifo[CIG_MST_FIFONUM];


// 0x40	 //
  	u32		cis_sync_delay[LL_CIS_IN_PER_CIG_MST_NUM_MAX];  //TODO: maybe not need
//	u8		cis_alloc_tbl[LL_CIS_IN_PER_CIG_MST_NUM_MAX];	//mark which CIS used for CIG, it's ordered
	u8		cis_order_tbl[LL_CIS_IN_PER_CIG_MST_NUM_MAX];
	u8		cis_arrgmt_map[LL_SE_IN_PER_CIG_MST_NUM_MAX]; //mark cis arrangement (according to the cis_idx)
} ll_cig_mst_t;

extern ll_cig_mst_t		*global_pCigMst;
extern ll_cig_mst_t		*latest_pCigMst;
extern ll_cig_mst_t		*blt_pCigMst;

extern int				blt_cigMstSel;

int 		blt_ll_searchExistingCigId(u8 cur_cigId);
int			blt_ll_AllocateNewCigId(u8 cur_cigId);
int	 		blt_ll_searchAvailableCig(u8 cur_cigId);

int 		blt_cig_mst_interrupt_task (int flag);
int 		blt_cig_mst_mainloop_task (int flag, void *p);

int 		blt_ctx_start (void);
int 		blt_ctx_post (void);
int			blt_cig_mst_start(int slotTask_idx);
int 		blt_ll_cis_master_mainloop(void);
int			blt_ll_buildCigSchedulerLinklist(void);
int 		blt_ll_cis_master_terminate_check();
int 		blt_ll_cis_master_cis_establish(st_ll_conn_t *pConn, ll_cis_conn_t * cur_pCisConn, ble_sts_t status);
int 		blt_ll_cigMstMainloop(void);

void		blt_ll_reset_cig_mst(void);
bool		blt_ll_sendCisReq(st_ll_conn_t *pConn, u8 acl_conn_idx);
bool		blt_ll_sendCisInd(st_ll_conn_t *pConn, u8 acl_conn_idx);
bool		blt_ll_rejectCisRsp(st_ll_conn_t *pConn, u8 acl_conn_idx);

ble_sts_t	blt_ll_cis_disconnect(u16 connHandle, u8 reason);
ble_sts_t 	blt_ll_cis_master_control_pdu_process(st_ll_conn_t* pConn, u16 acl_connHandle, u8 opcode, u8 *pLlCtrlPkt);

/******************************* cis_master end ********************************************************************/

















/******************************* cis_slave start ******************************************************************/
#define				CIG_SLV_FIFONUM 				16  //16*5mS(minimum) = 80mS
#define				CIS_REQ_ACCEPT_TIMEOUT			4000000 //TODO: 4s timeout unit:us

#define				CRX_EARLY_SET_SSLOT_NUM_MAX		7
#define				CRX_HALF_MARGIN_SSLOT_NUM_MAX	3

#define				SCHE_MODE_SUCCESSIVE			0
#define				SCHE_MODE_SEPARATED				1


_attribute_aligned_(4)
typedef struct {
	u8		acl_slave_idx;
	u8		sche_mode;
	u8		crx_early_set_sSlot_num;
	u8		crx_half_margin_sSlot_num;

	u8		cig_slv_idx;
	u8		getRxTimestamp;
	u8		cig_slv_occupied;
  	u8		cigId;

  	u8		cis_order_tbl[LL_CIS_IN_PER_CIG_SLV_NUM_MAX];
  	u8		cis_arrgmt_map[LL_SE_IN_PER_CIG_SLV_NUM_MAX]; //mark bis arrangement (according to the bis_idx)

  	u8		cis_alloc_count;	//How many CIS are established on the one CIG SLV
  	u8		packing; 			//Attention: keep align 4B
  	u16     link_acl_handle;	//link ACL_conn_hancle, associated ACL connection handle, u8 enough, u16 align here

	u8      cis_total_se_num;   //The cumulative number of cis arrangement mapping tables from the beginning of the idx0 to the last valid se (se may belong to different cis)
	u8      cis_se_en_num;
	u8      cis_arrgmt_next_idx;//Starting idx of cis arrangement mappings
	u8      cis_se_skip;		//If the part of the mapping table that is initially checked is invalid, it will skip to find the next valid CIS.

	u16		ciss_isoIntvl;      //unit: 1.25mS
	u16 	ciss_bSlotInterval;
	u16 	ciss_sSlotInterval;	//65536*20uS = 1.3S, slave interval can not exceed this value
  	u16		ciss_sSlotDuration;
  	u16		idle_interval_us;
  	u16		cisOffset_us;

  	u32     cis_arrgmt_map_msk; //Which idx are valid in the cis arrangement mapping table
    u32		cisOffset_tick;		/* CIS_Offset shall be set to the time, in microseconds */
//	u32		cig_expect_time;
//	u32		cig_anchor_point;
	u32 	cis_tolerance_time;
	u32		conn_duration;
	u32		cisSlvRxTick;
	s32		sSlot_mark_cig;
	u32		bSlot_mark_cig;

	u8		u8_rsvd22;
	u8		u8_rsvd33;
	u8		schTsk_wptr;
	u8		schTsk_rptr;

	//Attention: if not 4B aligned, task scheduler will collapse. SO variable must 4B aligned above !!!
	sch_task_t	schTsk_fifo[CIG_SLV_FIFONUM];

}ll_cig_slv_t;

extern ll_cig_slv_t		*global_pCigSlv;
extern ll_cig_slv_t		*latest_pCigSlv;
extern ll_cig_slv_t		*blt_pCigSlv;

extern int				blt_cigSlvSel;

int 		blt_cig_slv_interrupt_task (int flag);
int 		blt_cig_slv_mainloop_task (int flag);

int 		blt_cig_slv_start (int slotTask_idx);
int 		blt_crx_start(void);
int 		blt_crx_post(void);
int 		blt_ll_cigSlvMainloop(void);
int			blt_ll_calcCigSlv1stAndCis1stAnchorPoint(void);
int			blt_ll_buildCisSlaveSchedulerLinklist(void);
int 		blt_ll_cig_slave_terminate_check(void);
int 		blt_ll_cis_slave_cis_establish(st_ll_conn_t *pConn, ll_cis_conn_t * cur_pCisConn, ll_cig_slv_t * cur_pCisSlv, ble_sts_t status);

void		blt_ll_reset_cig_slv(void);
bool		blt_ll_sendCisRsp(st_ll_conn_t *pConn, u8 acl_conn_idx);
bool		blt_ll_rejectCisReq(st_ll_conn_t *pConn, u8 acl_conn_idx);

ble_sts_t   blt_llCisReqParamsChk(st_ll_conn_t* pc, rf_packet_ll_cis_req_t* pLlCisReq);
ble_sts_t 	blt_ll_cig_slave_control_pdu_process(st_ll_conn_t* pConn, u16 acl_connHandle, u8 opcode, u8 *pLlCtrlPkt);

/******************************* cis_slave end ********************************************************************/




/******************************* bis start ******************************************************************/
#define 	BIS_ROLE_BCST           					0
#define 	BIS_ROLE_SYNC             					1

#define		BIG_SLOT_BUILD_MSK							BIT(7)

//ISO interval shall be a multiple of 1.25mS in the range of 5ms to 4S
#define		BIG_FIFONUM									16  //16*5 = 80mS

/**
 *  @brief  Definition for BIG Control PDU Opcode
 */														// rf_len without MIC
#define		BIG_CHANNEL_MAP_IND							0x00			// 3
#define		BIG_TERMINATE_IND							0x01			// 7

#define		BLT_BIS_HANDLE								BIT(4)
#define 	BLT_BIS_IDX_MSK								(0x0F)

// BIG broadcast:	0x10/0x11	BIG SYNC:  0x12/0x13/0x14/0x15/0x16/0x17


#define		BIG_HANDLE_INVALID							(0xff)

// BIG_Handle: used to identify the BIG
#define 	BIG_ID_0									0
#define 	BIG_ID_1									1
#define 	BIG_ID_2									2
#define 	BIG_ID_3									3


//ISO BIS TX Data Buffer strcut begin
typedef	struct {
	u32 	payloadNumber;
	u32		eventCnt;
	u16		offset;
	u8 		RFU[2]; //4B align

	rf_packet_ll_data_t isoTxPdu;
}bis_tx_pdu_t;

typedef	struct {
	u32		fifo_size;

	u16     full_size; //fifo_size plus additional header
	u8		fifo_num;
	u8		rsvd;

	bis_tx_pdu_t* bis_tx_pdu;
}bis_tx_pdu_fifo_t;


_attribute_aligned_(4)
typedef struct {

	u8  bis_occupied;
	u8  bis_role;
	u16 bis_handle;

	//BIS TX buffer ctrl
	u8	isoPduTxFifoWptr;
	u8	isoPduTxFifoRptr;
	u8  txSduIdx;
	u8  txBnIdx;

	u8  txSduFifoWptr;
	u8  txSduFifoRptr;
	u8  first_pdu_flag;
	u8  curBisPhy;

	u8  rxSduFifoWptr;
	u8	rxSduFifoRptr;
	u8 	rx_first_pdu;
	u8	rxSduStatus;

	u8  big_idx;
	u8  nse;
	u8	bn;
	u8	irc;

	u16 max_pdu; //todo
	u8  phy;
	le_ci_prefer_t codingInd : 8; //u8  coding_ind;

	u32 lastPktSeqNum; // broadcast and sync share


	u32 sub_intervel_us;
	u32 sub_intervel_tick;
	u32 bis_spacing_us;
	u32 bis_spacing_tick;


	u64 curBisPldNum;
	u32 curRcvdPldNum;
	u32 curSendPldNum;
	u64	lastEventCnt;
	u64 lastPayloadNum; //broadcast and sync share

	u8  bisSubEventCnt;
	u8  link_big_handle;
	u8  bisSuccessiveMiss;
	u8  bisReceivePkt;
	
	u8 lossFlag;
	u8 numSdu2Pdu;
	u8 numSduEachEvent;
	u8 pto;

	// encryption concerned
	ble_crypt_para_t bisCryptCtrl; //for BIS encryption/decryption

	//Channel parameters
//	ll_mgrChnParam_t chnParam;  //reuse BIG's channel table information, removed to save RAM
  	u32		bisAccessAddr;		//AA shall be set to the Access Address of the BIS
  	u32		bisCrcInit;			//The BIS's CRC_Init value
  	u8		nxtRempChmTbl[40];	//can optimize to 37 later
  	u8		nxtNumUsedChn;
  	u8		nxtChmTbl[5];
  	u16		chnIdentifier;		//BISes use the same channel map as BIG, only ChnId different. Put outside
  							    //the structure 'll_mgrChnParam_t' to reuse channel table information and save RAM

#if (LL_FEATURE_ENABLE_CONNECTIONLESS_ISO)
  	iso_test_param_t	*pIsoTestParam;
#endif

}ll_bis_t;

typedef struct{
	//BIG use separated structure
	u8 maxNum_bigBcst; //used by BIG broadcast
	u8 curNum_bigBcst; //used by BIG broadcast

	u8 maxNum_bigSync; //used by BIG synchronization
	u8 curNum_bigSync; //used by BIG synchronization

	//BIS use common structure
	u8 maxNum_bisBcst;
	u8 curNum_bisBcst;
	u8 maxNum_bisSync;
	u8 curNum_bisSync;

	u8 maxNum_bisTotal; //maxNum_bisBcst + maxNum_bisSync

}ll_bis_mng_t;

extern ll_bis_t			   *global_pBis;
extern ll_bis_t			   *blt_pBis;
extern ll_bis_mng_t			bltBisMng;

extern int					blt_bis_sel;

extern rf_packet_ll_data_t* pCurrBisPdu;
extern rf_packet_ll_data_t  gBisNullPdu;
extern u8					gBisTermIndPdu[];
extern u8					gBisChmIndPdu[];

extern bis_tx_pdu_fifo_t		bltBisPduTxfifo;
/******************************* bis end ******************************************************************/




/******************************* bis_bcst start ***********************************************************/

//0:idly 1: pending 2: big create complete
#define		BIG_IN_IDLE									0
#define		BIG_CREATE_PENDING							1
#define		BIG_CREATE_COMPLETE							2
#define		BIG_CREATE_CANCELED							3
#define		BIG_TERM_COMPLETE							4

/**
 *  @brief  big_sc_flg: BIT(0): BIG rdy to send BISes; BIT(1): BIG rdy to send BIG Control
 */
#define		BIG_SC_RDY2SEND_BISES						BIT(0)
#define		BIG_SC_RDY2SEND_BIGCTRL						BIT(1)
#define		BIG_SC_RDY2END_BIGCTRL						BIT(3)

//BIT(0): BIG terminate; BIT(1): BIG channel update
#define		BIG_SC_TERM_IND								BIT(0)
#define		BIG_SC_CHM_IND								BIT(1)


//struct ll_prd_adv_para_t;



typedef struct{
	u32 bigOffset:		14;		//The time from the start of the packet containing the BIGInfo to the next BIG anchor point. bigOffset >= 600us
	u32 bigOffsetUnits:	 1;		//The actual time offset is determined by multiplying the value of BIG_Offset by the unit. unit: 300us or 30us
	u32 isoItvl:		12;		//ISO_Interval is the time between two adjacent BIG anchor points, in units of 1.25 ms. The value shall be between 4 and 3200 (i.e. 5 ms to 4 s).
	u32 numBis:			 5;		//The Num_BIS field shall contain the number of BISes in the BIG.

	u32 nse:			 5;		//NSE is the number of subevents per BIS in each BIG event. The value shall be between 1 and 31 and shall be an integer multiple of BN.
	u32 bn:				 3;		//The value of BN shall be between 1 and 7.
	u32 subItvl:		20;		//Sub_Interval is the time between the start of two consecutive subevents of each BIS.
	u32 pto:			 4;		//The value of PTO shall be between 0 and 15.

	u32 bisSpacing:		20;		//BIS_Spacing is the time between the start of corresponding subevents in adjacent BISes in the BIG and also the time between the start of the first
								//subevent of the last BIS and the control subevent, if present.
	u32 irc:			 4;		//The value of IRC shall be between 1 and 15.
	u32 maxPdu:			 8;		//Max_PDU is the maximum number of data octets (excluding the MIC, if any) that can be carried in each BIS Data PDU in the BIG. The value shall be
	                            //between 0 and 251 octets.

	u8  rfu;

	u32 seedAA; 				//The SeedAccessAddress field shall contain the Seed Access Address for the BIG

	u32 sduItvl:		20;		//Sub_Interval is the time between the start of two consecutive subevents of each BIS.
	u32 maxSdu:			12;		//Max_SDU is the maximum size of an SDU on this BIG

	u16 baseCrcInit;

	u8  chm37Phy3[5]; 			//The ChM field shall have the same meaning as the corresponding field in the CONNECT_IND PDU
								//The PHY field shall be set to indicate the PHY used by the BIG.0 LE 1M PHY; 1 LE 2M PHY; 2 LE Coded PHY
	u8  bisPldCnt39Framing1[5]; //The value shall be for the first subevent of the BIG event referred to by the BIG_Offset field
								//The Framing bit shall be set if the BIG carries framed data.
	u8  giv[8];
	u8  gskd[16];

}bigInfo_t;

_attribute_aligned_(4)
typedef struct {

	u8  cmd_status;  //0:idly 1: pending 2: big create complete
	u8 	big_test_cmd;
	u8 	bis_cnt;
	u8  big_role; // 0:broadcast  1: SYNC

	u8  big_handle;
	u8  adv_handle;
	u16 iso_itvl; //in units of 1.25 ms

	u32 sdu_intervel; //in units of us

	u16	max_sdu;
	u16 max_pdu;

	u8	nse;
	u8	phy;  //BIT(0): LE 1M; BIT(1): LE 2M; BIT(3): LE Coded PHY
	u8	big_sc_cssn;
	u8	big_sc_cstf;

	le_phy_type_t  curBisPhy : 8;
	le_ci_prefer_t codingInd : 8;
	u8	u8_rsvd[2]; //align

	u16 bis_handle[LL_BIS_IN_PER_BIG_BCST_NUM_MAX]; //keep bis handle; //4B align attention!!!

	u8	packing;
	u8	framing;
	u8	bn;
	u8	irc;

	u8	pto;
	u8	encryption;
	u8	big_terminated;
	u8	bis_total_se_num;

	u8	broadcast_code[16];    //big--endian

	// encryption concerned
	ble_crypt_para_t bigCtrlCrypt; //for BIG Control PDU encryption/decryption

	u32 se_length_tick;
	u32 MPT_T_IFS;
	u32 big_sync_delay_us;
	u32 transLatency_us;
	u32 big_ctrl_offset_us;

	u8  bis_arrgmt_map[LL_SE_IN_PER_BIG_BCST_NUM_MAX]; //mark bis arrangement (according to the bis_idx)

	u8  bis_arrgmt_next_idx;
	u8	bis_alloc_msk;			// mark which BIS allocate for current BIG, support 8 BIS max with "u8"
	u16	bSlot_interval_big;      // u16 can handle max 4S

	u32 seedAccessAddress;

	//Channel parameters
	ll_mgrChnParam_t chnParam;
	u32	scAccessCode;
	u32	scCrcInit;
  	u8	nxtRempChmTbl[40];	//can optimize to 37 later
  	u8	nxtNumUsedChn;
  	u8	nxtChmTbl[5];
  	u16	chnIdentifier;	//BISes use the same channel map as BIG, only ChnId different. Put outside
  						//the structure 'll_mgrChnParam_t' to reuse channel table information and save RAM

	/*
	 * The length of the BIGInfo is 33 octets for an unencrypted BIG and 57 octets for
	 *	an encrypted BIG, 60 for 4bytes align
	 */
	bigInfo_t BigInfor;
	u8	big_term_rsn;    //SC BIG terminate Reason
	u16 big_term_inst;   //SC BIG terminate Instant

	u16 big_chm_inst;    //SC BIG channel Instant
	u16  big_sc_mask;    //BIT(0): BIG terminate; BIT(1): BIG channel update

	u32 big_sc_send_cnt; //Record the cumulative number of BIG Control packets sent

//	u64 bigEventCnt;
	u32 bigEventCnt;

	u16 baseCrcInit;
	u8  bisSeq;
	u8	big_sc_flg;

  	u16	bSlot_duration_big;
  	u16	sSlot_duration_big;

  	u8	big_term_cmp_evt;
  	u8	big_chm_cmp_evt; //not used, remove latter TODO
  	u8	big_create_cmp_evt;
	u8  rsvd_evt;

	u32	bSlot_mark_big;
//	s32	sSlot_mark_big;	//not used now

	u16	schTsk_wptr;
	u16	schTsk_rptr;

	//Attention: if not 4B aligned, task scheduler will collapse. SO variable must 4B aligned above !!!
	sch_task_t	schTsk_fifo[BIG_FIFONUM];

}ll_big_bcst_t;


typedef struct{
	u8	opCode;
	u8	reason;
	u16 instant;
}big_termInd_data_t;

typedef struct{
	u8	opCode;
	u8	chm[5];
	u16 instant;
}big_chmInd_data_t;

typedef struct{
//	u64 bisEventCnt;
	rf_packet_ll_data_t isoRfPdu;
}iso_bis_pdu_t;


extern ll_big_bcst_t	*global_pBigBcst;
extern ll_big_bcst_t	*latest_pBigBcst;
extern ll_big_bcst_t	*blt_pBigBcst;

extern int				 blt_bigBcst_sel;


int 		blt_ll_searchExistingBigBcstHdl(u8 big_handle);
int 		blt_ll_AllocateNewBigBcstHdl(u8 big_handle);

int 		blt_big_bcst_interrupt_task (int flag);
int 		blt_big_bcst_mainloop_task (int flag, void *p);

int 		blt_bctx_start (void);
int 		blt_bctx_post (void);
int			blt_bigBcst_start(int slotTask_idx);

u32 		blt_ll_bis_getAccessCode(u32 seedAccessCode, u8 bisSeq);
u32 		blt_ll_bis_getSeedAccessAddr(void);
void		blt_ll_reset_big_bcst(void);
void 		blt_ll_bis_encryptPld(ble_crypt_para_t *pLeCryptCtrl , rf_packet_ll_data_t *pBisPdu, u64 txPayloadCnt);
/******************************* bis_bcst end ********************************************************************/






/******************************* bis_sync start ******************************************************************/
//0:idly 1: big synchronizing 2: big synchronized
#define		BIG_SYNC_IN_IDLE							0
#define		BIG_SYNCHRONIZING							1
#define		BIG_SYNCHRONIZED							2




typedef struct bis_rx_pdu_tag{
	struct bis_rx_pdu_tag	*next;
	u32 payloadNum;
	u32 idealPldAnchorTick;
	u8 rawData[24];//
}bis_rx_pdu_t;

typedef struct
{
	bis_rx_pdu_t	*pFree;
	bis_rx_pdu_t	*pUsed;

	u8	total_num;
	u8  fifo_size;
	u8	full_size;
	u8	freeNum;
}bis_rx_pdu_chain_t;

_attribute_aligned_(4)
typedef struct {

	u8 	big_state; //0:idly 1: big synchronizing 2: big synchronized
	u8 	bis_cnt;
	u8  big_role; // 0:broadcast  1: SYNC
	le_phy_type_t  curBisPhy : 8;

	le_ci_prefer_t codingInd : 8;
	u8	bigSyncEstEvt;
	u8	bigSyncEstEvtSts; /* status 0: succeed, others: failed */
	u8  bigSyncLostEvt;

	u8  big_handle;  // != 0xFF: unavailable, 0xFF: available
	u8	encrypt;
	u16 iso_itvl;	//in units of 1.25 ms


	u16 bis_handle[LL_BIS_IN_PER_BIG_SYNC_NUM_MAX]; //keep bis handle; //4B align attention!!!

	u8	packing;
	u8	framing;
	u8	bn;
	u8	irc;

	// encryption concerned
	ble_crypt_para_t bigCtrlCrypt; //for BIG Control PDU encryption/decryption

	u8	bis_total_se_num;
	u8	nse;
	u8	pto;
	u8	phy;  //BIT(0): LE 1M; BIT(1): LE 2M; BIT(3): LE Coded PHY

	u8	broadcast_code[16]; //big--endian
	u8  bis_arrgmt_map[LL_SE_IN_PER_BIG_SYNC_NUM_MAX]; //mark bis arrangement (according to the bis_idx)

	u8  bis_arrgmt_next_idx;
	u8	bis_alloc_msk;			// mark which BIS allocate for current BIG, support 8 BIS max with "u8"
	u16	bSlot_interval_big;      // u16 can handle max 4S

	u8  bisSyncRxNum;
	u8  getRxTimestamp;
	u16 u16_rsvd;

	u16	max_sdu;
	u16 max_pdu;

	u32 sdu_intervel;     //in units of us
	u32 bigSyncTimeoutUs; //Synchronization timeout for the BIG, in the units of 1us
	u32 big_sync_delay_us;
	u32 big_ctrl_offset_us;
	u32 transLatency_us;

	s32 sSlot_interval_big;
//	u32 iso_intvl_tick;  //not used now
	u32 MPT_T_IFS;
	u32 se_length_tick;
	u32 seedAccessAddress;

	//Channel parameters
	ll_mgrChnParam_t chnParam;
	u32	scAccessCode;
	u32	scCrcInit;
  	u8	nxtRempChmTbl[40];	//can optimize to 37 later
  	u8	nxtNumUsedChn;
  	u8	nxtChmTbl[5];
  	u16	chnIdentifier;
  	u16 rsvd1;

	/*
	 * The length of the BIGInfo is 33 octets for an unencrypted BIG and 57 octets for
	 *	an encrypted BIG, 60 for 4bytes align
	 */
	bigInfo_t BigInfor;
	u16 	  sync_handle;
	u8  	  bigTermSync;

	void* pPerdScanCB; //Periodic Scan data control block pointer, not used now


//	u64 bigEventCnt;
	u32 bigEventCnt;

	u16 baseCrcInit;
	u8  bisSeq;
	u8	big_sc_flg;

  	u16	bSlot_duration_big;
  	u16	sSlot_duration_big;

	u32	bSlot_mark_big;
	s32	sSlot_mark_big;


	/*
	 * Calibrate the local anchor point according to the RX receiving point
	 */
//	u32	bigSyncExpectTime; 		//unit: 1us * 16
//	u32	bigSyncAnchorPoint;		//unit: 1us * 16
	u32	bigSyncToleranceTime;	//unit: 1us * 16
	u32	bisSyncRxTick;			//unit: 1us * 16
	u32 bigSyncConnTick;		//unit: 1us * 16


	u16	schTsk_wptr;
	u16	schTsk_rptr;

	//Attention: if not 4B aligned, task scheduler will collapse. SO variable must 4B aligned above !!!
	sch_task_t	schTsk_fifo[BIG_FIFONUM];

	u8  mse;
	u8  num_bis;
	u8  bisIdx[LL_BIS_IN_PER_BIG_SYNC_NUM_MAX]; //List of indices of BISes

}ll_big_sync_t;

extern ll_big_sync_t	*global_pBigSync;
extern ll_big_sync_t	*latest_pBigSync;
extern ll_big_sync_t	*blt_pBigSync;

extern int				 blt_bigSync_sel;

extern bis_rx_pdu_chain_t		bltBisRxPduChain[LL_BIG_SYNC_NUM_MAX*LL_BIS_IN_PER_BIG_SYNC_NUM_MAX];
extern bis_rx_pdu_chain_t		*gBltBisRxPduChain;

u8*			blt_big_searchBisInfor(u8* pAcad, int acad_len);
int 		blt_big_sync_interrupt_task (int, void*);
int 		blt_big_sync_mainloop_task (int);

int 		blt_bsrx_start (void);
int 		blt_bsrx_post (void);
int			blt_bigSync_start(int slotTask_idx);

bool 		blt_ll_isBigSynchronizing(void);
int 		blt_ll_findExistingBigSyncHdl(u8 big_handle);
int 		blt_ll_AllocateNewBigSyncHdl(u8 big_handle);
int 		blt_ll_findBigSyncBySyncHdl(u16 sync_handle);
ble_sts_t	blt_bis_popRxEvtInfoToFifo(ll_bis_t *pBisSync);
void		blt_ll_reset_big_sync(void);
int			blt_ll_period_bisAcad_process(u8* bigInfor);
void		blt_ll_bis_duration_jump(ll_bis_t* pBisSync, u16 jumpBigEvtNum);
ble_sts_t	blt_bis_pushRxEvtInfoToFifo(ll_bis_t *pBisSync, rf_packet_ll_data_t* pIsoRxRawPkt);
ble_sts_t	blt_bis_deletePdu(bis_rx_pdu_chain_t *bisRxPduChain);
/******************************* bis_sync end ********************************************************************/




#endif /* ISO_STACK_H_ */
